package com.study.design.model.createPattern.singleton.singletonQuestion;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Constructor;

import org.junit.Test;

/**
* @Name: Client
* @Description: 单例模式漏洞测试类
* @Author: 李超	lc_jack@foxmail.com
* @CreateDate: 2017-2-9 下午8:27:31 
* @Version: V1.0
 */
public class Client {
	
	/**
	* @Name: testReflectSingleton
	* @Description: 通过反射破解单例模式
	* @Author: 李超	lc_jack@foxmail.com
	* @Version: V1.0
	* @CreateDate: 2017-2-9 下午8:28:14
	* @Parameters: 
	* @Return: void
	 */
	@Test
	public void testReflectSingleton() throws Exception {
		//获取单例对象
		Singleton ins01 = Singleton.getInstance() ;
		Singleton ins02 = Singleton.getInstance() ;
		System.out.println(ins01.hashCode());
		System.out.println(ins02.hashCode());
		//通过反射绕过单例，获取多个实例化对象
		@SuppressWarnings("unchecked")
		Class<Singleton> clazz = (Class<Singleton>) Class.forName("com.study.design.model.singleton.question.Singleton") ;
		Constructor<Singleton> constructor = clazz.getDeclaredConstructor() ;
		//取消权限访问检查
		constructor.setAccessible(true) ;
		Singleton ins03 = constructor.newInstance() ;
		System.out.println(ins03.hashCode());
	}
	
	/**
	* @Name: testSerializableSingleton
	* @Description: 通过反序列化破解单例模式
	* @Author: 李超	lc_jack@foxmail.com
	* @Version: V1.0
	* @CreateDate: 2017-2-9 下午8:28:14
	* @Parameters: 
	* @Return: void
	 */
	@Test
	public void testSerializableSingleton() throws Exception {
		//获取单例对象
		Singleton ins01 = Singleton.getInstance() ;
		Singleton ins02 = Singleton.getInstance() ;
		System.out.println(ins01.hashCode());
		System.out.println(ins02.hashCode());
		//将ins01对象序列化到 d:/myjava/a.txt 文件中
		FileOutputStream fos = new FileOutputStream("d:/myjava/a.txt") ;
		ObjectOutputStream oos = new ObjectOutputStream(fos) ;
		oos.writeObject(ins01) ;
		oos.close() ;
		fos.close() ;
		//通过反序列化获取新的实例化对象
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream("d:/myjava/a.txt")) ;
		Singleton ins03 = (Singleton) ois.readObject() ;
		System.out.println(ins03.hashCode());
	}

}













